/**
 * Created by 居胜 on 2016/7/29.
 */

/**
 * 所有组件的公共基类，提供统一的接口，
 */
function Widget() {
    this.$boundingBox = null;    //属性：最外层的容器
}

Widget.prototype = {

    renderUI : function () {},      //接口：添加dom节点

    bindUI : function () {},        //接口：监听事件

    syncUI : function () {},        //接口，初始化组件属性

    //方法：渲染组件
    render : function (container) {
        this.renderUI();
        this.bindUI();
        this.syncUI();
        $(container || document.body).append(this.$boundingBox);
    },

    //接口：销毁前的处理函数
    destructor : function () {},

    //方法：销毁组件
    destroy : function () {
        this.destructor();
        if(this.$boundingBox){
            this.$boundingBox.off();
            this.$boundingBox.remove();
        }
    }
};

/**********************************************************************************************************************/

/**
 * tooltip.js
 */
function ToolTip() {
    
    //默认参数
    this.options = {
        target : null,
        text : 'tooltip',
        direction : 'right'
    }
}

ToolTip.prototype = $.extend({}, new Widget(), {

    renderUI : function () {

        //初始化节点
        this.$boundingBox = $('<span class="jqr-tooltip jqr-tooltip-'+ this.options.direction +'">'+ this.options.text +'</span>');
    }, 

    bindUI : function () {

        var self = this;
        //监听事件
        $(this.options.target).on('mouseleave', function () {
            self.destroy();
        })
    },

    syncUI : function () {

        //初始化 tooltip 属性
        $(this.options.target).css({
            'position' : 'relative'
        });
    },

    destructor : function () {
        
        $(this.options.target).css({
            'position' : 'relative'
        });
    },

    tip : function (options) {
        //配置参数
        $.extend(this.options, options);
        this.render(this.options.target);
        return this;
    }
});

var tooltip_toggle = '[jqr-tooltip]';

$(document).on('mouseenter.tooltip', tooltip_toggle, function () {
    
    new ToolTip().tip({
        target : event.target,
        text : $(event.target).attr('jqr-tooltip'),
        direction : $(event.target).attr('direction')
    })
});


/**********************************************************************************************************************/
/**
 * dropdown.js
 */
function DropDown() {

    //默认参数
    this.options = {
        target: null,
        callback: function () {
        }
    }
}

DropDown.prototype = $.extend({}, new Widget(), {

    //初始化
    renderUI : function(){

        this.$parent = this.options.target.closest('.jqr-dropdown');
        this.$dropdown_menu = this.$parent.find('.jqr-dropdown-menu');
        this.$dropdown_menu_list = this.$dropdown_menu.find('li');
    },

    //渲染属性
    syncUI : function () {
        this.$dropdown_menu.css('display', 'block');
        this.randNum = Math.random();
    },

    //事件监听
    bindUI : function () {

        var self = this;
        //点击 li, 关闭下拉框
        this.$dropdown_menu_list.each(function (i, elem) {

            $(elem).on('click', function () {
                event.preventDefault();
                self.$returnValue = $(this).text();
                if(self.options.callback){
                    self.options.callback(self.$returnValue);
                }
                self.destroy();
                
            });
        });

        //点击空白区域，关闭下拉框
        $(document).on('click.dropdown.other' + this.randNum, function () {

            if(!self.$parent.is(event.target) && self.$parent.has(event.target).length ===0){
                self.destroy();
            }
        })

    },

    //销毁前的处理函数
    destructor : function () {

        //去除 li 身上的 click 监听
        this.$dropdown_menu_list.each(function (i, elem) {
            $(elem).off();
        });

        $(document).off('click.dropdown.other' + this.randNum);

        this.$dropdown_menu.css('display', 'none');
    },

    show : function (options) {
        $.extend(this.options, options);
        this.render();

    }
});

var dropdown_toggle = '[data-toggle="jqr-dropdown"]';

$(document).on('click.dropdown', dropdown_toggle, function () {

    var target = $(event.target);
    new DropDown().show({
        target : target,
        callback : function (value) {
            target.html(value);
        }
    });
});


/**********************************************************************************************************************/
/**
 * Dialog.js 
 */
function Dialog(){
    this.options = {
        target : null,      //要显示的dialog
        width : '',         //dialog 宽度
        height: '',         //dialog 高度
        hasMask : true,     //模态

        closeBtn : '',      //关闭按钮
        //关闭按钮回调函数
        closefn : function () {
        },               

        submitBtn : '',     //提交按钮
        //提交按钮回调函数
        submitfn : function () {
            
        }
    }
}

Dialog.prototype = $.extend({}, new Widget(), {
   
    renderUI : function () {
        if(this.options.hasMask){
            this.$boundingBox = $('<div class="mask"></div>');
        }
    },

    //软编码设置参数
    syncUI : function () {
        if(this.options.width){
            this.options.target.css('width', this.options.width);
        }

        if(this.options.height){
            this.options.target.css('height', this.options.height);
        }
        
        if(!this.options.closeBtn){
            this.options.closeBtn = $('.dialog-close');
        }
        
        if(!this.options.submitBtn){
            this.options.submitBtn = $('.dialog-submit');
        }

        this.options.target.css('display', 'block');
    },
    
    bindUI : function () {

        var self = this;

        //点击关闭按钮
        this.options.closeBtn.on('click.dialog', function () {
            if(self.options.closefn){
                self.options.closefn();
                self.destroy();
            }
        });

        //点击提交按钮
        this.options.submitBtn.on('click.dialog', function () {
            if(self.options.submitfn){
                self.options.submitfn();
                self.destroy();
            }
        });
        
        //点击空白区域
        $(document).on('click.dialog.other', function () {
            if(!self.options.target.is(event.target) && self.options.target.has(event.target).length === 0){
                self.destroy();
            }
        })
    },
    
    destructor : function () {
        this.options.target.css('display', 'none');

        //移出事件监听
        this.options.closeBtn.off('click.dialog');
        this.options.submitBtn.off('click.dialog');
        $(document).off('click.dialog.other');
    },

    //对外接口
    show : function (options) {
        $.extend(this.options, options);
        if(this.options.target){
            this.render();
        }
    }
});

var dialog_toggle = '[data-toggle="jqr-dialog"]';

$(document).on('click.dialog', dialog_toggle, function (event) {
    
    var target = $(event.target).attr('data-target');

    new Dialog().show({
        target : $(target),

        closeBtn : $('.dialog-close'),
        closefn : function () {
            alert('close callback function')
        },

        submitBtn : $('.dialog-submit'),
        submitfn : function () {
            alert('submit callback function')
        }
    });
    
});

/**********************************************************************************************************************/


/*pagination.js*/
function Pagination() {

    this.options = {
        target : null,
        maxPage : null,
        currentPage : 1,
        callback : function () {}
    }
}

Pagination.prototype = $.extend({}, new Widget(), {

    renderUI : function () {
        this.changePage(parseInt(this.options.currentPage), parseInt(this.options.maxPage));

        //自定义组件
        this.options.target.attr('hasOne', 'true');
    },

    syncUI : function () {
    },

    bindUI : function () {

        var self = this;
        self.$list = this.$boundingBox.find('li').slice(0, 9);
        //为分页绑定点击事件
        self.$list.each(function (i, elem) {

            $(elem).on('click.pagination', function () {
                var pageIndex = parseInt($(elem).attr('href').substring(1));
                if(!isNaN(pageIndex)){

                    self.options.currentPage = pageIndex;

                    //回调函数
                    if(self.options.callback){
                        self.options.callback(pageIndex);
                    }

                    //重新渲染
                    self.destroy();
                    self.render(self.options.target);
                }
            })
        });
    },

    destructor : function () {

        //移除分页点击事件
        this.$list.each(function (i, elem) {
            $(elem).off('click.pagination');
        });

    },

    //渲染分页效果
    changePage : function (currentPage, maxPage) {

        this.$boundingBox = $('<ul></ul>');

        var temp;
        //首页
        temp = $('<li class="firstPage" href="#'+ 1 +'">首页</li>');
        this.$boundingBox.append(temp);

        //上一页
        if(currentPage>=2){
            temp = $('<li class="prePage" href="#'+ (currentPage-1) +'">上一页</li>');
        }else {
            temp = $('<li class="prePage" href="#">上一页</li>');
        }
        this.$boundingBox.append(temp);

        //总页数小于5
        if(maxPage<=5) {
            for (var i = 1; i <= maxPage; i++) {
                temp = $('<li href="#'+ i +'">' + i + '</li>');

                if (currentPage == i) {
                    temp.addClass('active');
                }
                this.$boundingBox.append(temp);
            }
        }
            //总页数大于5
        else {
            for(var j=1; j<=5; j++){

                //当前处于第一二页
                if(currentPage==1 || currentPage==2){
                    temp = $('<li href="#'+ j +'">'+ j +'</li>');

                    if (currentPage == j) {
                        temp.addClass('active');
                    }
                    this.$boundingBox.append(temp);
                }

                    //当前处于最后两页
                else if((maxPage-currentPage)==0 || (maxPage-currentPage)==1){
                    temp = $('<li href="#'+ (maxPage-5+j) +'">'+ (maxPage-5+j) +'</li>');

                    if (currentPage == (maxPage-5+j)) {
                        temp.addClass('active');
                    }
                    this.$boundingBox.append(temp);
                }

                else {
                    temp = $('<li href="#'+ (currentPage-3+j) +'">'+ (currentPage-3+j) +'</li>');
                    if(currentPage == (currentPage-3+j)){
                        temp.addClass('active');
                    }
                    this.$boundingBox.append(temp);
                }
            }
        }

        //下一页
        if((maxPage - currentPage)>=1){
            temp = $('<li class="nextPage" href="#'+ (currentPage+1) +'">下一页</li>');
        }else {
            temp = $('<li class="nextPage" href="#">下一页</li>');
        }
        this.$boundingBox.append(temp);

        //尾页
        temp = $('<li class="lastPage" href="#'+ maxPage +'">尾页</li>');
        this.$boundingBox.append(temp);

        //info
        temp = $('<li class="info">第'+ currentPage +'页/共'+ maxPage +'页</li>');
        this.$boundingBox.append(temp);

    },

    show : function (options) {
        $.extend(this.options, options);
        if(this.options.target.attr('hasOne')){
            this.options.target.find('ul').remove();
        }
        this.render(this.options.target);
    }
});

var pagination_toggle = '.jqr-pagination';

$(function () {

    var self = $(pagination_toggle);

    self.each(function (i, elem) {

        new Pagination().show({
            target : $(elem),
            maxPage : $(elem).attr('data-maxPage'),
            currentPage : $(elem).attr('data-currentPage'),

            callback : function (value) {}
        });
    });
});

/**********************************************************************************************************************/


/**
 * calender.js
 */
function Calender() {
    
    this.options = {
        target : null,
        limitDay : 0,
        callback : function () {}
    }
}

Calender.prototype = $.extend({}, new Widget(), {

    //初始化日历节点
    renderUI : function () {

        //calender容器
        this.$boundingBox = $("<div class='calender'></div>");

        //title
        this.$boundingBox.append($('<div class="title">' +
                                        '<span class="last_year">'+ "&lt;&lt;" +'</span>' +
                                        '<span class="last_month">&lt;</span>' +
                                        '<span class="year"></span>' +
                                        '<span class="month"></span>' +
                                        '<span class="next_month">&gt;</span>' +
                                        '<span class="next_year">&gt;&gt;</span>' +
                                    '</div>'));

        //table
        this.$table = $('<table><thead><tr><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr></thead></table>');

        var $tbody = $('<tbody></tbody>');
        var $tr;
        for(var i=0; i<6; i++){

            $tr = $('<tr></tr>');
            $tr.append('<td></td><td></td><td></td><td></td><td></td><td></td><td></td>');
            $tbody.append($tr);
        }

        this.$table.append($tbody);
        this.$boundingBox.append(this.$table);
    },

    //动态设置内容
    syncUI : function () {

        //bug修复，为document监听的click事件，创建不同的命名空间，防止冲突
        this.randNum = Math.random();
        this.limitDay = parseInt(this.options.limitDay);

        var date = new Date();
        this.setContent(date.getFullYear(), date.getMonth()+1, date.getDate());
    },

    //绑定事件
    bindUI : function () {

        var self = this;

        //点击日期td, 触发回调
        this.$table.find('td').each(function (i, elem) {
            $(elem).on('click.calender', function () {

                var value = parseInt(self.$boundingBox.find('.year').html())+ '-' +
                            parseInt(self.$boundingBox.find('.month').html()) + '-' +
                            $(elem).html();

                if(!self.limitDay || (self.limitDay && $(elem).css('cursor') !== 'not-allowed')) {

                    if (self.options.callback) {
                        self.options.callback(value);
                    }
                    self.destroy();
                }
            })
        });

        //点击按钮，改变日期年月
        this.$boundingBox.find('.title').on('click.calender', function () {
            var $target = $(event.target),
                year = parseInt(self.$boundingBox.find('.year').html()),
                month = parseInt(self.$boundingBox.find('.month').html());

            if($target.hasClass('last_month')){
                if(--month == 0){
                    year--;
                    month = 12;
                }

            }else if($target.hasClass('next_month')){
                if(++month == 13){
                    year++;
                    month = 1;
                }

            }else if($target.hasClass('last_year')){
                year--;

            }else if($target.hasClass('next_year')){
                year++;
            }
            self.setContent(year, month, new Date().getDate());
        });

        //点击空白区域, 关闭日历
        $(document).on('click.calender.other' + this.randNum, function () {
            if(!self.$wrap.is(event.target) && self.$wrap.has(event.target).length === 0){
                self.destroy();
            }
        });
    },

    destructor : function () {
        $(document).off('click.calender.other' + this.randNum);
    },

    //设置table内容
    setContent : function (year, month, day) {

        var self = this,
            date = new Date(year, month -1 ,1),
            dayNo = date.getDay(),
            dayCount;

        //年、月
        this.$boundingBox.find('.year').html(year + '年');
        this.$boundingBox.find('.month').html(month + '月');

        //日
        this.$tds = this.$table.find('td');

        //改变当前年月，重新显示前，移出旧有的内容
        this.$tds.each(function (i, elem) {
            $(elem).html('').removeClass('active limited hover');
        });

        //这个月最后一天是几号
        switch (month) {
            case 1: case 3: case 5: case 7: case 8: case 10: case 12:
                dayCount = 31;
                break;

            case 4: case 6: case 9: case 11:
                dayCount = 30;
                break;

            case 2:
                if((year%4 ==0 && year%100 !== 0) || year%400 === 0){
                    dayCount = 29;
                }else {
                    dayCount = 28;
                }
                break;
        }


        //动态生成日期
        for(var i=dayNo; i<(dayCount+dayNo); i++){

            this.$tds.eq(i).html(i-dayNo+1);

            var isAllowDay = this.limitDay && Math.abs(day - (i-dayNo+1)) <= (this.limitDay/2);
            if(!this.limitDay || isAllowDay){

                //为当前日，添加active, 其他的添加hover
                day === (i-dayNo+1) ? this.$tds.eq(i).addClass('active') : this.$tds.eq(i).addClass('hover');

            }else {
                this.$tds.eq(i).addClass('limited');
            }
        }
    },

    show : function (options) {
        $.extend(this.options, options);

        this.$wrap = this.options.target.closest('.calender_wrap');
        this.render(this.$wrap);
    }
});

var calender_toggle = "[data-toggle='jqr-calender']";

$(document).on('click.calender', calender_toggle, function () {
   
    var $target = $(event.target);
    $target.html('');
    
    new Calender().show({
        target : $target,
        limitDay : $target.attr('data-limitDay'),
        callback : function (value) {
            $target.html(value);
        }
    })

});


/**********************************************************************************************************************/


function Carousel() {
    this.options = {
        target : null,
        direction : 'horizontal',
        width : '',
        height : ''
    }
}

Carousel.prototype = $.extend({}, new Widget(), {

    renderUI : function () {
        
        //轮播框当前页圆点
        this.$boundingBox = $('<ul class="pages"></ul>');

        this.$ul = this.options.target.find('.items');
        this.$aLis = this.$ul.find('li');

        for(var i=0; i<this.$aLis.length; i++){
            this.$boundingBox.append($('<li>'+ (i+1) +'</li>'));
        }

        this.$boundingBox.find('li').eq(0).addClass('active');
        this.options.target.append(this.$boundingBox);

        this.$pagesLi= this.options.target.find('.pages li');
    },
    
    syncUI : function () {

        if(this.options.width){
            this.options.target.css('width', this.options.width);
        }

        if(this.options.height){
            this.options.target.css('height', this.options.height);
        }

        switch (this.options.direction) {
            case 'horizontal':

                //设置li与容器大小相同
                this.$aLis.css({
                    'width' : this.options.target.width(),
                    'height' : this.options.target.height(),
                    'float': 'left'
                });

                //设置ul宽度
                this.wrapWidth = this.options.target.width();
                var length = this.wrapWidth * this.$aLis.length;
                this.$ul.css('width',  length);
                break;
        }
    },
    
    bindUI : function () {

        var self = this;
        this.nowIndex = 0;
        //轮播动画
        this.timer = setInterval(startMove, 3000);

        function startMove() {

            clearInterval(self.timer);

            if(++self.nowIndex == self.$aLis.length) {
                self.nowIndex = 0;
            }

            //pages
            self.$pagesLi.eq(self.nowIndex).addClass('active').siblings().removeClass('active');

            self.$ul.animate({'left' : -self.$aLis.eq(0).width()}, 400, 'linear', function () {

                //拷贝节点，无缝循环
                var $prevOne = self.$ul.find('li').eq(0).clone();
                self.$ul.append($prevOne);
                self.$ul.find('li').eq(0).remove();
                self.$ul.css('left', 0);

                self.timer = setInterval(startMove, 3000);
            })
        }

        //向后翻页
        this.$after = this.options.target.find('.after');

        this.$after.on('click', function () {

            if(++self.nowIndex == self.$aLis.length) {
                self.nowIndex = 0;
            }

            //pages
            self.$pagesLi.eq(self.nowIndex).addClass('active').siblings().removeClass('active');

            self.$ul.animate({'left' : -self.$aLis.eq(0).width()}, 400, 'linear', function () {

                //拷贝节点，无缝循环
                var $prevOne = self.$ul.find('li').eq(0).clone();
                self.$ul.append($prevOne);
                self.$ul.find('li').eq(0).remove();
                self.$ul.css('left', 0);
            })
        });

        //向前翻页
        this.$before = this.options.target.find('.before');

        this.$before.on('click', function () {

            if(--self.nowIndex == -1) {
                self.nowIndex = self.$aLis.length-1;
            }

            //pages分页图标
            self.$pagesLi.eq(self.nowIndex).addClass('active').siblings().removeClass('active');

            var $lastOne = self.$ul.find('li').eq(-1).clone();
            self.$ul.prepend($lastOne).css('left', -self.wrapWidth);
            self.$ul.find('li').eq(-1).remove();

            self.$ul.animate({'left' : 0}, 400, 'linear')
        });

        this.options.target.hover(
            function () {

                //鼠标移入
                clearInterval(self.timer);
                self.$after.css('display','inline');
                self.$before.css('display','inline');
            },

            function () {

                //鼠标移出
                self.$after.css('display','none');
                self.$before.css('display','none');
                self.timer = setInterval(startMove, 3000);
            }
        );
    },
    
    destructor : function () {
    },
    
    show : function (options) {
        $.extend(this.options, options);
        this.render(this.options.target);
    }
});

var carousel_toggle = ".jqr-carousel";

$(function () {

    var self = $(carousel_toggle);

    self.each(function (i, elem) {
        new Carousel().show({
            target : $(elem),
            direction : 'horizontal'
        });
    })
});













